package controller

import (
	"github.com/cn-ygf/go-admin/internal/action"
	"github.com/cn-ygf/go-admin/internal/modular/system/model"
	"github.com/cn-ygf/go-admin/internal/modular/system/service"
	"github.com/cn-ygf/go-admin/internal/modular/system/vo"
	"github.com/cn-ygf/go-admin/pkg/utils"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/mvc"
)

// RoleController 角色管理
type RoleController struct {
	Ctx iris.Context
}

// PostList 分页查询角色
func (c *RoleController) PostList(req vo.QueryRoleListReq) mvc.Result {
	if !hasPermi(c.Ctx, "system:role:list") {
		return nil
	}
	var (
		err   error
		list  []*model.SysRole
		total int64
	)
	if req.PageSize > 1000 {
		req.PageSize = 1000
	}
	if req.Params != nil {
		req.Params.BeginTime = req.Params.BeginTime / 1000
		req.Params.EndTime = req.Params.EndTime / 1000
	}

	list, total, err = service.RoleService.QueryList(&req)
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.ServerError()
	}
	resultList := make([]*vo.QueryRoleEntity, len(list))
	for index, item := range list {
		resultList[index] = &vo.QueryRoleEntity{
			RoleID:            item.RoleID,
			RoleName:          item.RoleName,
			RoleKey:           item.RoleKey,
			RoleSort:          item.RoleSort,
			DataScope:         item.DataScope,
			MenuCheckStrictly: item.MenuCheckStrictly,
			DeptCheckStrictly: item.DeptCheckStrictly,
			Status:            item.Status,
			Remark:            item.Remark,
			CreatedAt:         item.CreatedAt,
		}
	}
	return action.Data(map[string]any{
		"rows":  resultList,
		"total": total,
	})
}

// PutStatus 修改状态
func (c *RoleController) PutStatus(req vo.ChangeRoleStatusReq) mvc.Result {
	if !hasPermi(c.Ctx, "system:user:edit") {
		return nil
	}
	var (
		err error
	)
	if req.RoleId == 1 {
		return action.AdminError()
	}
	if req.Status != "0" && req.Status != "1" {
		return action.ParamError()
	}
	err = service.RoleService.ChangeStatus(req.RoleId, req.Status)
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.ServerError()
	}
	return action.OK()
}

// GetBy 根据id获取角色信息
func (c *RoleController) GetBy(roleId int64) mvc.Result {
	if !hasPermi(c.Ctx, "system:role:query") {
		return nil
	}
	role, err := service.RoleService.GetByID(roleId)
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.ServerError()
	}
	return action.Data(&vo.QueryRoleEntity{
		RoleID:            role.RoleID,
		RoleName:          role.RoleName,
		RoleKey:           role.RoleKey,
		RoleSort:          role.RoleSort,
		DataScope:         role.DataScope,
		MenuCheckStrictly: role.MenuCheckStrictly,
		DeptCheckStrictly: role.DeptCheckStrictly,
		Status:            role.Status,
		Remark:            role.Remark,
		CreatedAt:         role.CreatedAt,
	})
}

// Post 修改角色
func (c *RoleController) Post(req vo.AddRoleReq) mvc.Result {
	if !hasPermi(c.Ctx, "system:role:add") {
		return nil
	}
	req.CreateBy = getCurrentUser(c.Ctx).UserName
	err := service.RoleService.Add(&req)
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.ServerError()
	}
	return action.OK()
}

// Put 修改角色
func (c *RoleController) Put(req vo.EditRoleReq) mvc.Result {
	if !hasPermi(c.Ctx, "system:role:edit") {
		return nil
	}
	if req.RoleId == 1 {
		return action.AdminError()
	}
	req.UpdateBy = getCurrentUser(c.Ctx).UserName
	err := service.RoleService.Update(&req)
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.ServerError()
	}
	return action.OK()
}

// DeleteBy 删除角色
func (c *RoleController) DeleteBy(idStr string) mvc.Result {
	if !hasPermi(c.Ctx, "system:role:remove") {
		return nil
	}
	ids := utils.IdsStrToInt64(idStr)
	if len(ids) < 1 {
		return action.ParamError()
	}
	err := service.RoleService.Delete(ids)
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.ServerError()
	}
	return action.OK()
}

// GetDeptTreeBy 角色关联权限树形
func (c *RoleController) GetDeptTreeBy(roleId int64) mvc.Result {
	if !hasPermi(c.Ctx, "system:role:query") {
		return nil
	}
	deptIds, err := service.DeptService.GetIdsByRoleId(roleId)
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.ServerError()
	}
	root, err := service.DeptService.SelectTree()
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.ServerError()
	}
	return action.Data(map[string]any{
		"depts":       root,
		"checkedKeys": deptIds,
	})
}

// PutScope 修改数据权限范围
func (c *RoleController) PutScope(req vo.DataScopeReq) mvc.Result {
	if !hasPermi(c.Ctx, "system:role:edit") {
		return nil
	}
	if req.RoleId == 1 {
		return action.AdminError()
	}
	err := service.RoleService.DataScope(&req)
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.ServerError()
	}
	return action.OK()
}

// PostAuthUserUnallocatedList 查询不存在关联的用户
func (c *RoleController) PostAuthUserUnallocatedList(req vo.AllocatedListReq) mvc.Result {
	if !hasPermi(c.Ctx, "system:role:list") {
		return nil
	}
	var (
		err   error
		list  []*model.SysUser
		total int64
	)
	if req.PageSize > 1000 {
		req.PageSize = 1000
	}

	list, total, err = service.RoleService.UnallocatedList(&req)
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.ServerError()
	}
	resultList := make([]*vo.QueryUserListEntity, len(list))
	for index, item := range list {
		resultList[index] = &vo.QueryUserListEntity{
			UserID:      item.UserID,
			DeptID:      item.DeptID,
			UserName:    item.UserName,
			NickName:    item.NickName,
			UserType:    item.UserType,
			Email:       item.Email,
			Phonenumber: item.Phonenumber,
			Sex:         item.Sex,
			Avatar:      item.Avatar,
			Status:      item.Status,
			Remark:      item.Remark,
			CreatedAt:   item.CreatedAt,
		}
	}
	return action.Data(map[string]any{
		"rows":  resultList,
		"total": total,
	})
}

// PostAuthUserAllocatedList 查询角色关联的用户
func (c *RoleController) PostAuthUserAllocatedList(req vo.AllocatedListReq) mvc.Result {
	if !hasPermi(c.Ctx, "system:role:list") {
		return nil
	}
	var (
		err   error
		list  []*model.SysUser
		total int64
	)
	if req.PageSize > 1000 {
		req.PageSize = 1000
	}

	list, total, err = service.RoleService.AllocatedList(&req)
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.ServerError()
	}
	resultList := make([]*vo.QueryUserListEntity, len(list))
	for index, item := range list {
		resultList[index] = &vo.QueryUserListEntity{
			UserID:      item.UserID,
			DeptID:      item.DeptID,
			UserName:    item.UserName,
			NickName:    item.NickName,
			UserType:    item.UserType,
			Email:       item.Email,
			Phonenumber: item.Phonenumber,
			Sex:         item.Sex,
			Avatar:      item.Avatar,
			Status:      item.Status,
			Remark:      item.Remark,
			CreatedAt:   item.CreatedAt,
		}
	}
	return action.Data(map[string]any{
		"rows":  resultList,
		"total": total,
	})
}

// PutAuthUserSelect 用户绑定角色
func (c *RoleController) PutAuthUserSelect(req vo.AuthUserSelectReq) mvc.Result {
	if !hasPermi(c.Ctx, "system:role:edit") {
		return nil
	}
	err := service.RoleService.BindUser(req.RoleId, req.UserIds)
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.ServerError()
	}
	return action.OK()
}

// PutAuthUserCancel 取消授权
func (c *RoleController) PutAuthUserCancel(req vo.AuthUserCancelReq) mvc.Result {
	if !hasPermi(c.Ctx, "system:role:edit") {
		return nil
	}
	err := service.RoleService.UnbindUser(req.RoleId, req.UserId)
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.ServerError()
	}
	return action.OK()
}

// PutAuthUserCancelAll 取消授权
func (c *RoleController) PutAuthUserCancelAll(req vo.AuthUserCancelAllReq) mvc.Result {
	if !hasPermi(c.Ctx, "system:role:edit") {
		return nil
	}
	for _, userId := range req.UserIds {
		err := service.RoleService.UnbindUser(req.RoleId, userId)
		if err != nil {
			systemLog.Errorln(err.Error())
			return action.ServerError()
		}
	}

	return action.OK()
}

// PostExport 导出角色
func (c *RoleController) PostExport() mvc.Result {
	if !hasPermi(c.Ctx, "system:role:export") {
		return action.RawError()
	}
	roleList, err := service.RoleService.GetList()
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.RawError()
	}
	titleRow := []string{"角色序号", "角色名称", "权限字符", "状态"}
	statusMaps, err := service.DictDataService.GetDictMaps("sys_normal_disable")
	if err != nil {
		systemLog.Errorln(err.Error())
		return action.RawError()
	}
	data := make([][]any, len(roleList))
	for index, item := range roleList {
		row := make([]any, 11)
		row[0] = item.RoleID
		row[1] = item.RoleName
		row[2] = item.RoleKey
		row[3] = statusMaps[item.Status]
		data[index] = row

	}
	return action.ExportExcel(data, titleRow)
}
